package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	"nettools/server/config"
	"nettools/server/handler"
	"nettools/shared/models"
	"nettools/shared/utils"
)

// Server 服务器实例
type Server struct {
	config    *models.ServerConfig
	connMgr   *handler.ConnectionManager
	listeners map[string]interface{} // 保持向后兼容
	mu        sync.RWMutex
	running   bool
}

// NewServer 创建新的服务器实例
func NewServer(cfg *models.ServerConfig) *Server {
	return &Server{
		config:    cfg,
		listeners: make(map[string]interface{}),
	}
}

// Start 启动服务器
func (s *Server) Start() error {
	utils.Info("正在启动NetTools服务器...")
	utils.Info("服务器配置: %s:%d", s.config.Host, s.config.Port)

	// 创建连接管理器
	s.connMgr = handler.NewConnectionManager(
		s.config.MaxConnections,
		s.config.MaxServicesPerClient,
		s.config.Performance.ConnectionTimeout.ToDuration(),
	)

	// 注册所有服务
	if err := s.registerServices(); err != nil {
		return fmt.Errorf("注册服务失败: %w", err)
	}

	// 开始监听所有服务
	if err := s.connMgr.StartListening(s.config.Host); err != nil {
		return fmt.Errorf("启动监听失败: %w", err)
	}

	s.running = true
	utils.Info("✅ NetTools服务器启动成功!")
	utils.Info("管理端口: %s:%d", s.config.Host, s.config.Port)

	// 启动状态监控
	go s.startStatusMonitor()

	return nil
}

// registerServices 注册所有服务
func (s *Server) registerServices() error {
	utils.Info("注册服务...")

	// 注册管理服务（用于内网客户端连接）
	if err := s.connMgr.RegisterService("management", s.config.Port, "management", true, "", 0); err != nil {
		return fmt.Errorf("注册管理服务失败: %w", err)
	}

	// 注册所有代理服务
	for _, service := range s.config.Services {
		if !service.Enabled {
			utils.Info("跳过禁用的服务: %s", service.Name)
			continue
		}

		utils.Info("注册代理服务: %s -> 端口 %d", service.Name, service.Port)
		if err := s.connMgr.RegisterService(service.Name, service.Port, service.ServiceType, service.Remote, service.TargetIP, service.TargetPort); err != nil {
			return fmt.Errorf("注册服务 %s 失败: %w", service.Name, err)
		}

		// 保持向后兼容性，存储服务信息
		s.mu.Lock()
		s.listeners[service.Name] = service
		s.mu.Unlock()
	}

	utils.Info("✅ 所有服务注册完成")
	return nil
}

// startStatusMonitor 启动状态监控
func (s *Server) startStatusMonitor() {
	ticker := time.NewTicker(30 * time.Second)
	defer ticker.Stop()

	for s.running {
		select {
		case <-ticker.C:
			clientCount := s.connMgr.GetClientCount()
			sessionCount := s.connMgr.GetSessionCount()
			utils.Info("📊 状态监控 - 客户端: %d, 活跃会话: %d", clientCount, sessionCount)
		}
	}
}

// Stop 停止服务器
func (s *Server) Stop() error {
	utils.Info("正在停止NetTools服务器...")
	s.running = false

	if s.connMgr != nil {
		if err := s.connMgr.Close(); err != nil {
			utils.Error("关闭连接管理器失败: %v", err)
		}
	}

	utils.Info("✅ NetTools服务器已停止")
	return nil
}

// GetStats 获取服务器统计信息
func (s *Server) GetStats() map[string]interface{} {
	stats := make(map[string]interface{})

	if s.connMgr != nil {
		stats["clients"] = s.connMgr.GetClientCount()
		stats["sessions"] = s.connMgr.GetSessionCount()
	}

	stats["running"] = s.running
	stats["services"] = len(s.config.Services)

	return stats
}

func main() {
	// 检查命令行参数，支持默认配置文件
	var configPath string
	if len(os.Args) >= 2 {
		configPath = os.Args[1]
	} else {
		configPath = "configs/config.json"
		utils.Info("未指定配置文件，使用默认配置: %s", configPath)
	}

	utils.Info("🚀 启动NetTools服务器")
	utils.Info("配置文件: %s", configPath)

	// 加载配置文件
	cfg, err := config.LoadConfig(configPath)
	if err != nil {
		log.Fatalf("❌ 加载配置文件失败: %v", err)
	}

	// 创建服务器实例
	server := NewServer(cfg)

	// 设置信号处理
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	// 启动服务器
	if err := server.Start(); err != nil {
		log.Fatalf("❌ 启动服务器失败: %v", err)
	}

	// 输出启动信息
	utils.Info("🎯 服务器已启动，按 Ctrl+C 停止...")
	stats := server.GetStats()
	utils.Info("📋 服务统计:")
	utils.Info("   - 已注册服务: %d", stats["services"])
	utils.Info("   - 最大连接数: %d", cfg.MaxConnections)
	utils.Info("   - 每客户端最大服务数: %d", cfg.MaxServicesPerClient)

	// 等待信号
	select {
	case sig := <-sigChan:
		utils.Info("📝 接收到信号: %v", sig)
	case <-ctx.Done():
		utils.Info("📝 上下文取消")
	}

	// 优雅关闭
	utils.Info("🛑 正在优雅关闭服务器...")
	if err := server.Stop(); err != nil {
		log.Printf("❌ 关闭服务器时出错: %v", err)
	}

	utils.Info("👋 服务器已成功关闭")
}
